
//
// 121227 - AH - Created.
// 121230 - AH - Clear methods.
// 

package org.japril.jutil;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

/**
 * <p>
 *   Represents text that is composed of parts which can be appended to 
 *   independently. 
 * </p>
 * @author Arne Halvorsen (AH)
 */
public final class ComposedText 
{
  private final CharArrayWriter[] m_parts;
  
  private final PrintWriter[] m_writers;
  
  private final int m_lastIdx;
  
  private final int m_partCount;
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param n Number of parts.
   */
  public ComposedText(int n)
  {
    if (n<1)
    {
      throw new IllegalArgumentException("n<1 : "+n);
    }
    
    m_partCount=n;
    
    m_parts=new CharArrayWriter[n];
    m_writers=new PrintWriter[n];
    for (int i=0; i<n; i++)
      m_writers[i]=new PrintWriter(m_parts[i]=new CharArrayWriter());

    m_lastIdx=n-1;
  }
  
  /**
   * <p>
   *   Gets number of parts text is composed of.
   * </p>
   * @return Count.
   */
  public int getPartCount(){ return m_partCount; }
  
  /**
   * <p>
   *   Gets partial text.
   * </p>
   * @param part Index of part to get.
   * @return Partial text.
   * @throws IndexOutOfBoundsException 
   *         If {@code part<0 || part>=getPartCount()}.
   */
  public String getPart(int part){ return m_parts[part].toString(); }
  
  /**
   * <p>
   *   Prints line shift.
   * </p>
   * @param part Part to print to.
   * @return {@code this}.
   * @throws IndexOutOfBoundsException 
   *         If {@code part<0 || part>=getPartCount()}. 
   */
  public ComposedText println(int part)
  {
    PrintWriter pw=m_writers[part];
    pw.println();
    return this;
  }
  
  /**
   * <p>
   *   Prints a line.
   * </p>
   * @param part Part to print to.
   * @param txt  Text of line. If {@code null} prints "null".
   * @return {@code this}.
   * @throws IndexOutOfBoundsException 
   *         If {@code part<0 || part>=getPartCount()}. 
   */
  public ComposedText println(int part, String txt)
  {
    txt=(txt==null) ? "null" : txt;
    PrintWriter pw=m_writers[part];
    pw.println(txt);
    return this;
  }
  
  /**
   * <p>
   *   Prints.
   * </p>
   * @param part Part to print to.
   * @param txt  Text to print. If {@code null} prints "null".
   * @return {@code this}.
   * @throws IndexOutOfBoundsException 
   *         If {@code part<0 || part>=getPartCount()}. 
   */
  public ComposedText print(int part, String txt)
  {
    txt=(txt==null) ? "null" : txt;
    PrintWriter pw=m_writers[part];
    pw.print(txt);
    return this;
  }
  
  /**
   * <p>
   *   Prints line shift to first part.
   * </p>
   * @return {@code this}. 
   */
  public ComposedText println(){ return println(0); }
  
  /**
   * <p>
   *   Prints a line to first part.
   * </p>
   * @param txt Text of line. If {@code null} prints "null".
   * @return {@code this}. 
   */
  public ComposedText println(String txt){ return println(0, txt); }
  
  /**
   * <p>
   *   Prints to first part.
   * </p>
   * @param txt  Text to print. If {@code null} prints "null".
   * @return {@code this}. 
   */
  public ComposedText print(String txt){ return print(0, txt); }
  
  /**
   * <p>
   *   Clears all text.
   * </p>
   */
  public void clear()
  {
    int n=m_partCount;
    for (int i=0; i<n; i++)
      m_writers[i]=new PrintWriter(m_parts[i]=new CharArrayWriter());
  }
  
  /**
   * <p>
   *   Clears part.
   * </p>
   * @param part Index of part to clear.
   * @throws IndexOutOfBoundsException 
   *         If {@code part<0 || part>=getPartCount()}. 
   */
  public void clear(int part)
  {
    m_writers[part]=new PrintWriter(m_parts[part]=new CharArrayWriter());
  }
  
  /**
   * <p>
   *   Clears parts.
   * </p>
   * @param parts Indexes of parts to clear.
   * @throws IndexOutOfBoundsException If 
   *         {@code parts[i]<0 || parts[i]>=getPartCount()} for
   *         {@code i>=0 || i<parts.length}.
   */
  public void clear(int... parts)
  {
    if (parts==null)
    {
      throw new NullPointerException("parts");
    }
    
    int n=parts.length;
    for (int i=0; i<n; i++)
    {
      int curr=parts[i];
      m_writers[curr]=new PrintWriter(m_parts[curr]=new CharArrayWriter());
    }
  }
  
  private final StringBuilder m_sb=new StringBuilder();
  
  @Override
  public String toString() 
  {
    if (m_lastIdx==0) return m_parts[0].toString();
    int n=m_partCount;
    StringBuilder sb=m_sb;
    sb.setLength(0);
    for (int i=0; i<n; i++)
    {
      m_writers[i].flush();
      sb.append(m_parts[i]);
    }
    return sb.toString();
  }
  
}
